﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using FingerTip.Infrastructure;
using FingerTip.Infrastructure.Extensions;
using Newtonsoft.Json;

namespace FingerTip.Infrastructure.SampleHttpClient
{
    public class HttpRequestor
    {
        private object _data;

        private readonly string _url;
        private readonly MethodType _type;

        public HttpRequestor(string url, MethodType type)
        {
            this._url = url;
            this._type = type;
        }

        public HttpRequestor With(object data)
        {
            _data = data;
            return this;
        }

        public T To<T>(string tailUrl)
        {
            var result = default(T);

            void Parser(string json)
            {
                result = JsonConvert.DeserializeObject<T>(json);
            }

            Stream(tailUrl, Parser);
            return result;
        }

        private static HttpWebRequest SetupConnection(string url, MethodType methodType)
        {
            var request = (HttpWebRequest) WebRequest.Create(url);
            request.Method = methodType.ToString().ToUpperInvariant();
            request.ContinueTimeout = 60000;
            SetAuthHeader(request);
            return request;
        }

        private static void SetAuthHeader(WebRequest request)
        {
            request.Credentials = CredentialCache.DefaultCredentials;
            string base64Credentials = GetEncodedCredentials();
            request.Headers.Add("Authorization", "Basic " + base64Credentials);
        }

        private bool HasOutput()
        {
            return _type == MethodType.Post || _type == MethodType.Put && _data != null;
        }

        private void SubmitData(HttpWebRequest request)
        {
            request.ContentType = "application/json";

            var data = Encoding.GetEncoding("UTF-8").GetBytes(_data.ToJson());

            //请求流
            var requestStream = request.GetRequestStream();
            requestStream.Write(data, 0, data.Length);
            requestStream.Close();
        }

        public void Stream(string apiUrl, Action<string> parser)
        {
            var request = SetupConnection(_url + apiUrl, _type);

            if (HasOutput())
            {
                SubmitData(request);
            }

            using (var response = (HttpWebResponse) request.GetResponse())
            {
                using (var stream = response.GetResponseStream())
                {
                    var streamReader = new StreamReader(stream, Encoding.GetEncoding("UTF-8"));
                    var result = streamReader.ReadToEnd();
                    streamReader.Close();
                    stream.Close();
                    parser(result);
                }
            }
        }

        private static string GetEncodedCredentials()
        {
            var mergedCredentials = $"{"config.uesrname"}:{"config.password"}";
            var byteCredentials = Encoding.UTF8.GetBytes(mergedCredentials);
            return Convert.ToBase64String(byteCredentials);
        }
    }
}
